package com.stox.charting.ui.swing.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
import javax.swing.plaf.basic.BasicInternalFrameUI;

import prefuse.util.ui.JRangeSlider;

import com.stox.charting.ui.swing.event.listener.ChartingInternalFrameViewResizeListener;
import com.stox.charting.ui.swing.event.listener.RangeSliderChangeListener;
import com.stox.charting.ui.swing.model.Theme;
import com.stox.charting.ui.swing.model.Zoom;
import com.stox.charting.ui.swing.model.indicator.VolumeChart;
import com.stox.charting.ui.swing.model.price.PriceChartView;
import com.stox.core.ui.swing.view.InternalFrameView;
import com.stox.core.ui.swing.wrapper.JSplitPane;
import com.stox.ioc.Container;
import com.stox.resources.i18n.MessageSource;

public class ChartingInternalFrameView extends InternalFrameView {
	private static final long serialVersionUID = 8674132374681697843L;

	private PriceChartView priceChartView;
	private VolumeChart volumeChart;
	private final List<ChartView> indicatorChartViews = new ArrayList<ChartView>();
	private final JRangeSlider rangeSlider = new JRangeSlider(0,10000,0,10000,JRangeSlider.HORIZONTAL, JRangeSlider.LEFTRIGHT_TOPBOTTOM);
	private boolean lastSelected = true;
	private final Zoom zoom = new Zoom(rangeSlider);
	
	private static final List<ChartingInternalFrameView> list = new LinkedList<ChartingInternalFrameView>();
	private static InternalFrameListener removalListener = new InternalFrameAdapter(){
		@Override
		public void internalFrameActivated(InternalFrameEvent e) {
			super.internalFrameActivated(e);
			setLastSelectedView((ChartingInternalFrameView)e.getSource());
		}
		
		@Override
		public void internalFrameOpened(InternalFrameEvent e) {
			super.internalFrameOpened(e);
			setLastSelectedView((ChartingInternalFrameView)e.getSource());
		}
		
		@Override
		public void internalFrameDeiconified(InternalFrameEvent e) {
			super.internalFrameDeiconified(e);
			setLastSelectedView((ChartingInternalFrameView)e.getSource());
		}
		
		@Override
		public void internalFrameDeactivated(InternalFrameEvent e) {
			super.internalFrameDeactivated(e);
			if(!list.isEmpty()){
				setLastSelectedView(list.get(0));
			}
		}
		
		@Override
		public void internalFrameIconified(InternalFrameEvent e) {
			super.internalFrameIconified(e);
			if(!list.isEmpty()){
				setLastSelectedView(list.get(0));
			}
		}
		
		@Override
		public void internalFrameClosed(InternalFrameEvent e) {
			super.internalFrameClosed(e);
			list.remove(e.getSource());
			if(!list.isEmpty()){
				setLastSelectedView(list.get(0));
			}
		}
	};
	
	public static List<ChartingInternalFrameView> getChartingInternalFrameViews(){
		return list;
	}

	public static ChartingInternalFrameView getLastSelectedView(){
		for(ChartingInternalFrameView view : list){
			if(view.isLastSelected()){
				return view;
			}
		}
		return null;
	}
	
	private static void setLastSelectedView(ChartingInternalFrameView view){
		for(ChartingInternalFrameView v : list){
			v.setLastSelected(false);
		}
		view.setLastSelected(true);
	}
	
	private void setLastSelected(boolean value){
		this.lastSelected = value;
		BasicInternalFrameUI ui = (BasicInternalFrameUI)getUI();
		ui.getNorthPane().setBackground(value?Color.green:Color.red);
	}
	
	public ChartingInternalFrameView() {
		super(MessageSource.getMessage("Chart"));
		list.add(this);
		addInternalFrameListener(removalListener);
		setLastSelectedView(this);
		addMouseWheelListener(zoom);
		new ChartingDropTargetListener(this);
	}
	
	public void afterPropertiesSet(){
		setLayout(new BorderLayout());
		addComponentListener(Container.get(ChartingInternalFrameViewResizeListener.class));
		add(rangeSlider, BorderLayout.SOUTH);
		rangeSlider.addChangeListener(new RangeSliderChangeListener(this));
		setPriceChartView(new PriceChartView(this)); 
		setVolumeChart(new VolumeChart());
		revalidate();
	}
	
	@Override
	public void revalidate() {
		super.revalidate();
		if(getIndicatorChartViews() != null){
			for(ChartView chartView : getIndicatorChartViews()){
				chartView.setPreferredSize(chartView.getParent().getSize());
				for(int i = 0; i < chartView.getChartCount(); i++){
					chartView.getChart(i).setSize(chartView.getChart(i).getParent().getSize());
				}
			}
		}
		if(priceChartView != null && priceChartView.getParent() != null){
			priceChartView.setPreferredSize(priceChartView.getParent().getSize());
			priceChartView.setSize(priceChartView.getParent().getSize());
			int rangeSliderHeight = (int)priceChartView.getChartingInternalFrameView().getRangeSlider().getPreferredSize().getHeight();
			Dimension dimension = priceChartView.getPreferredSize();
			priceChartView.getContentPane().setPreferredSize(
					new Dimension((int)dimension.getWidth() - Theme.getStructure().getVerticalAxisWidth()*2, 
					(int)(dimension.getHeight() - rangeSliderHeight - Theme.getStructure().getHorizontalAxisHeight()*2)));
			priceChartView.getContentPane().setSize(priceChartView.getContentPane().getPreferredSize());
			for(int i = 0; i < priceChartView.getChartCount(); i++){
				priceChartView.getChart(i).setSize(priceChartView.getChart(i).getParent().getSize());
			}
		}
	}

	public void repaintChartViews(){
		priceChartView.repaint();
		for(ChartView chartView : indicatorChartViews){
			chartView.repaint();
		}
	}
	
	public JRangeSlider getRangeSlider() {
		return rangeSlider;
	}
	
	public PriceChartView getPriceChartView() {
		return priceChartView;
	}

	public void setPriceChartView(PriceChartView priceChartView) {
		this.priceChartView = priceChartView;
		getContentPane().add(priceChartView,BorderLayout.CENTER);
	}
	
	public void addIndicatorChartView(ChartView chartView){
		if(!indicatorChartViews.contains(chartView)){
			indicatorChartViews.add(chartView);
			JSplitPane splitPane = new JSplitPane();
			Component componet = getContentPane().getComponent(0);
			remove(componet);
			splitPane.setTopComponent(componet);
			splitPane.setBottomComponent(chartView);
			getContentPane().add(splitPane);
			revalidate();
		}
	}
	
	public List<ChartView> getIndicatorChartViews() {
		return indicatorChartViews;
	}
	
	public void removeIndicatorChartView(ChartView chartView){
		indicatorChartViews.remove(chartView);
	}

	public VolumeChart getVolumeChart() {
		return volumeChart;
	}

	public void setVolumeChart(VolumeChart volumeChart) {
		this.volumeChart = volumeChart;
		if(volumeChart != null && !volumeChart.isIndependent()){
			priceChartView.setVolumeChart(volumeChart);
		}
	}

	public boolean isLastSelected() {
		return lastSelected;
	}

	public Zoom getZoom() {
		return zoom;
	}
	
}
